package com.tccmeta.matchmaker.controller;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.util.SignUtils;
import com.tccmeta.matchmaker.PayVo;
import com.tccmeta.matchmaker.wxSdk.JsSdk;
import com.tccmeta.matchmaker.wxSdk.Sign;
import com.tccmeta.po.Meta;
import com.tccmeta.servlce.MetaService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.script.ScriptException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : Gentle
 * @date : 2019/5/17 12:11
 * @description:
 */
@RestController
@Slf4j
@RequestMapping(value = "/wechat/pay/")
public class WeChatPayController {

    @Resource
    private WxPayService wxPayService;

    @Resource
    private WxMpService wxMpService;
    @Resource
    private MetaService metaService;

    /**
     * 此处处理订单信息，构建订单数据。
     * <p>
     * 将构建好的支付参数返回到前端，前端调起微信支付
     *
     * @return
     */
    @PostMapping(value = "weChatPay")
    public ResponseEntity weChatPay(@RequestBody PayVo payVo) {
        /**
         * 处理内部业务，校验订单等
         */
        final WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()
                //调起支付的人的 openId
                .openid(payVo.getOpenId())
                //订单编号
                .outTradeNo(payVo.getTradeNo())
                //订单金额
                .totalFee(yuanToFee(new BigDecimal(payVo.getAmount())))
                //商品描述
                .body(payVo.getRemark())
                //获取本地IP
                .spbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress())
                //回调的 URL 地址
                .notifyUrl(wxPayService.getConfig().getNotifyUrl())
                .build();
        log.info("微信支付参数：{}", wxPayUnifiedOrderRequest);
        WxPayUnifiedOrderResult wxPayUnifiedOrderResult = null;
        try {
            wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
        } catch (WxPayException e) {
            e.printStackTrace();
            throw new RuntimeException("该订单不可支付！");
        }
        //组合参数构建支付
        Map<String, String> paySignInfo = new HashMap<>(5);
        String timeStamp = createTimestamp();
        String nonceStr = String.valueOf(System.currentTimeMillis());
        paySignInfo.put("appId", wxPayService.getConfig().getAppId());
        paySignInfo.put("nonceStr", nonceStr);
        paySignInfo.put("timeStamp", timeStamp);
        paySignInfo.put("signType", "MD5");
        paySignInfo.put("package", "prepay_id=" + wxPayUnifiedOrderResult.getPrepayId());
        String paySign = SignUtils.createSign(paySignInfo, "MD5", wxPayService.getConfig().getMchKey(), false);

        //组合支付参数
        Map<String, Object> result = new HashMap<>();
        result.put("appId", wxPayService.getConfig().getAppId());
        result.put("nonceStr", nonceStr);
        result.put("paySign", paySign);
        result.put("signType", "MD5");
        result.put("prepayId", wxPayUnifiedOrderResult.getPrepayId());
        result.put("timeStamp", timeStamp);

        return ResponseEntity.ok(result);
    }

    /**
     * 微信配置获取config
     *
     * @return
     */
    @PostMapping(value = "/config")
    public JsSdk getWxConfig(@RequestBody JsSdk wxPaySdk) {
        log.info("输出URL{}", wxPaySdk.getUrl());
        JsSdk sign = Sign.sign(wxPaySdk.getUrl(), wxMpService.getWxMpConfigStorage().getAppId(), wxMpService.getWxMpConfigStorage().getJsapiTicket());
        return sign;
    }

    /**
     * @param xmlData 微信返回的流
     * @return
     */
    @RequestMapping(value = "weChatPayNotify", method = {RequestMethod.GET, RequestMethod.POST})
    public String weChatNotify(@RequestBody String xmlData) {
        try {
            final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);
            /**
             * 系统内部业务，修改订单状态之类的
             */
            System.out.println("微信支付回调" + notifyResult.getOutTradeNo());
            Meta node = Meta.builder().build();
            try {
                node.setId(Long.parseLong(notifyResult.getOutTradeNo()));
                node.setData("付费订单");
                metaService.save(node);
            } catch (ScriptException e) {
                e.printStackTrace();
            }
            //成功后回调微信信息
            return WxPayNotifyResponse.success("回调成功！");
        } catch (WxPayException e) {
            e.printStackTrace();
            return WxPayNotifyResponse.fail("回调有误!");
        }
    }

    /**
     * 1 块钱转为 100 分
     * 元转分
     *
     * @param bigDecimal 钱数目
     * @return 分
     */
    private int yuanToFee(BigDecimal bigDecimal) {
        return bigDecimal.multiply(new BigDecimal(100)).intValue();
    }

    /**
     * 时间
     *
     * @return 时间戳
     */
    private String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}
